Function.RegisterNamespace("System.Web.Threading");

System.Web.Threading.ThreadState={
    Initialized:"Initialized",
    Disposed:"Disposed",
    Running:"Running",
    Suspended:"Suspended"
};

System.Web.Threading.Thread=function(){
    // Private Members
    var _delegate;
    var _objectContext;
    var _this;
    var _state;
    var _timer={
        timeout:0
    };
    
    // Public Members
    this.ThreadState;
    
    // ctor
    function Thread(delegate,interval){
        if(!Object.IsType(Function,delegate))throw new Error("System.Web.Threading.Thread.ctor: 'delegate' must be a valid Function pointer.");
        if(!Object.IsType(Number,interval))throw new Error("System.Web.Threading.Thread.ctor: 'interval' must be a valid Number.");
        if(Math.round(interval)!=interval)throw new Error("System.Web.Threading.Thread.ctor: 'interval' must be a whole Number.");
        if(interval<0)throw new Error("System.Web.Threading.Thread.ctor: 'interval' must be a Number greater than or equal to zero (0).");
        _delegate=delegate;
        _timer.timeout=interval;
        _this=this;
        setState(System.Web.Threading.ThreadState.Initialized);
    }
    Thread.apply(this,arguments);
    
    // IDisposable Members
    this.Dispose=function(){
        clearTimer();
        setState(System.Web.Threading.ThreadState.Disposed);
        _delegate=_this=null;
    };
    
    // Public Methods
    this.GetDelegate=function(){
        return _delegate;
    };
    
    this.GetInterval=function(){
        return _timer.timeout;
    };
    
    this.Resume=function(immediate){
        if(_state!=System.Web.Threading.ThreadState.Suspended)throw new Error(String.Format("System.Web.Threading.Thread.Resume: 'Resume' is not a valid operation for the state '{0}'.",_state));
        setState(System.Web.Threading.ThreadState.Running);
        return setTimer(immediate&&1);
    };

    this.SetInterval=function(interval){
        if(!Object.IsType(Number,interval))throw new Error("System.Web.Threading.Thread.SetInterval: 'interval' must be a valid Number.");
        if(Math.round(interval)!=interval)throw new Error("System.Web.Threading.Thread.SetInterval: 'interval' must be a whole Number.");
        if(interval<0)throw new Error("System.Web.Threading.Thread.SetInterval: 'interval' must be a Number greater than or equal to zero (0).");
        _timer.timeout=interval;
    };

    this.Start=function(objectContext){
        if(_state!=System.Web.Threading.ThreadState.Initialized)throw new Error(String.Format("System.Web.Threading.Thread.Start: 'Start' is not a valid operation for the state '{0}'.",_state));
        _objectContext=arguments.length?Array.prototype.slice.call(arguments,0):null;
        setState(System.Web.Threading.ThreadState.Running);
        step();
    };

    this.Suspend=function(){
        if(_state!=System.Web.Threading.ThreadState.Running)throw new Error(String.Format("System.Web.Threading.Thread.Suspend: 'Suspend' is not a valid operation for the state '{0}'.",_state));
        setState(System.Web.Threading.ThreadState.Suspended);
        clearTimer();
    };
    
    // Private Methods
    function clearTimer(){
        if(_timer.timer)Object.Global().clearTimeout(_timer.timer);
    }
    
    function setState(state){
        _this.ThreadState=_state=state;
    }
    
    function setTimer(interval){
        _timer.timer=Object.Global().setTimeout(step,interval||_timer.timeout);
    }

    function step(){
        var context={
            Cancel:false,
            Instance:_this,
            Interval:_timer.timeout
        };
        _delegate.apply(_this,[context].concat(_objectContext));
        if(context.Cancel)return _this.Suspend();
        if(context.Interval!=_timer.timeout)_this.SetInterval(context.Interval);
        setTimer();
    }
};